package controller;

import model.Checkerboard;

/**
 *
 * @author Martin
 */
public class cMove {

    /**
     * Checks if the specified jump is possible
     * @param c checkerboard controller
     * @param x1 start x position
     * @param y1 start y position
     * @param x2 destination x position
     * @param y2 destination y position
     * @return true if the jump is valid, false if not valid
     */
    public static boolean checkJump(cCheckerboard c, int x1, int y1, int x2, int y2) {
        return null != getJump(c, x1, y1, x2, y2);
    }

    /**
     * Returns captured piece's position as int[] with x = result[0], y = result[1]
     * @param c checkerboard controller
     * @param x1 start x position
     * @param y1 start y position
     * @param x2 destination x position
     * @param y2 destination y position
     * @return captured piece's position as int[] with x = result[0], y = result[1]
     */
    public static int[] getJump(cCheckerboard c, int x1, int y1, int x2, int y2) {
        int piece = c.getCheckerboard().getPiece(x1, y1);
        int dest = c.getCheckerboard().getPiece(x2, y2);
        int capturedX = -1, capturedY = -1;
        if (piece == Checkerboard.EMPTY || dest != Checkerboard.EMPTY) {
            return null;
        }

        int directionX = x2 - x1 > 0 ? 1 : -1;
        int directionY = y2 - y1 > 0 ? 1 : -1;
        // Pawn
        if (piece == Checkerboard.P1_PAWN || piece == Checkerboard.P2_PAWN) {
            if ((x2 - x1 == 2 || x2 - x1 == -2) && (y2 - y1 == 2 || y2 - y1 == -2)) {
                if (piece == Checkerboard.P1_PAWN
                        && (c.getCheckerboard().getPiece(x1 + directionX, y1 + directionY) == Checkerboard.P2_PAWN
                        || c.getCheckerboard().getPiece(x1 + directionX, y1 + directionY) == Checkerboard.P2_QUEEN)) {
                    return new int[]{x1 + directionX, y1 + directionY};
                }
            }
            if (piece == Checkerboard.P2_PAWN
                    && (c.getCheckerboard().getPiece(x1 + directionX, y1 + directionY) == Checkerboard.P1_PAWN
                    || c.getCheckerboard().getPiece(x1 + directionX, y1 + directionY) == Checkerboard.P1_QUEEN)) {
                return new int[]{x1 + directionX, y1 + directionY};
            }
            return null;
        }
        // Queen
        // The move is diagonal
        if ((x2 - x1) * directionX == (y2 - y1) * directionY) {
            // All Squares between are empty but one
            int nbPiecesEnemy = 0;
            for (int i = 1; i < (x2 - x1) * directionX - 1; i++) {
                int aPiece = c.getCheckerboard().getPiece(x1 + i * directionX, y1 + i * directionY);
                if (aPiece != Checkerboard.EMPTY) {
                    // Same player's piece stops analysis
                    if ((piece == Checkerboard.P1_QUEEN && (aPiece == Checkerboard.P1_QUEEN || aPiece == Checkerboard.P1_PAWN))
                            || (piece == Checkerboard.P2_QUEEN && (aPiece == Checkerboard.P2_QUEEN || aPiece == Checkerboard.P2_PAWN))) {
                        return null;
                    }
                    // Count enemies
                    if ((piece == Checkerboard.P1_QUEEN && (aPiece == Checkerboard.P2_QUEEN || aPiece == Checkerboard.P2_PAWN))
                            || (piece == Checkerboard.P2_QUEEN && (aPiece == Checkerboard.P1_QUEEN || aPiece == Checkerboard.P1_PAWN))) {
                        nbPiecesEnemy++;
                        capturedX = x1 + i * directionX;
                        capturedY = y1 + i * directionY;
                    }
                }
            }
            if (nbPiecesEnemy == 1) {
                return new int[]{capturedX, capturedY};
            }
        }
        return null;


    }

    /**
     * Performs jump if it is valid and returns captured piece's position as int[] with x = result[0], y = result[1];
     * returns null if the jump is not valid
     * @param c checkerboard controller
     * @param x1 start x position
     * @param y1 start y position
     * @param x2 destination x position
     * @param y2 destination y position
     * @return captured piece's position as int[] with x = result[0], y = result[1];
     * returns null if the jump is not valid
     */
    public static int[] jump(cCheckerboard c, int x1, int y1, int x2, int y2) {
        int[] gj = getJump(c, x1, y1, x2, y2);
        if (gj != null) {
            int piece = c.getCheckerboard().getPiece(x1, y1);
            c.getCheckerboard().setPiece(x2, y2, piece);
            c.getCheckerboard().setPiece(x1, y1, Checkerboard.EMPTY);
            c.getCheckerboard().setPiece(gj[0], gj[1], Checkerboard.EMPTY);
        }
        return gj;
    }

    /**
     * Checks if the specified move is possible
     * @param c checkerboard controller
     * @param x1 start x position
     * @param y1 start y position
     * @param x2 destination x position
     * @param y2 destination y position
     * @return true if the move is valid, false if not valid
     */
    public static boolean checkMove(cCheckerboard c, int x1, int y1, int x2, int y2) {
        int piece = c.getCheckerboard().getPiece(x1, y1);
        int dest = c.getCheckerboard().getPiece(x2, y2);
        if (piece == Checkerboard.EMPTY || dest != Checkerboard.EMPTY) {
            return false;
        }
        // Pawn
        if (piece == Checkerboard.P1_PAWN || piece == Checkerboard.P2_PAWN) {
            return ((piece == Checkerboard.P1_PAWN && (x2 - x1 == 1 || x2 - x1 == -1) && y2 - y1 == 1
                    || piece == Checkerboard.P2_PAWN && (x2 - x1 == 1 || x2 - x1 == -1) && y2 - y1 == -1));
        }
        // Queen
        int directionX = x2 - x1 > 0 ? 1 : -1;
        int directionY = y2 - y1 > 0 ? 1 : -1;
        // The move is diagonal
        if ((x2 - x1) * directionX == (y2 - y1) * directionY) {
            // All Squares between are empty
            for (int i = 1; i < (x2 - x1) * directionX - 1; i++) {
                if (c.getCheckerboard().getPiece(x1 + i * directionX, y1 + i * directionY) != Checkerboard.EMPTY) {
                    return false;
                }
            }
            return true;
        }
        return false;
    }

    /**
     * Performs the specified move if it is a valid move, returns true if move was performed,
     * false if it wasn't
     * @param c checkerboard controller
     * @param x1 start x position
     * @param y1 start y position
     * @param x2 destination x position
     * @param y2 destination y position
     * @return true if the move is valid and performed, false if not valid and not performed
     */
    public static boolean move(cCheckerboard c, int x1, int y1, int x2, int y2) {
        if (checkMove(c, x1, y1, x2, y2)) {
            int piece = c.getCheckerboard().getPiece(x1, y1);
            c.getCheckerboard().setPiece(x2, y2, piece);
            c.getCheckerboard().setPiece(x1, y1, Checkerboard.EMPTY);
            return true;
        }
        return false;
    }
}
